package label_center

import (
	"fmt"
	"reflect"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

// 追踪日志
type Log struct {
	Id       int64  `json:"Id"`       //编号
	AppId    string `json:"AppId"`    //应用Id
	ClientIP string `json:"ClientIP"` //客户IP
	TransId  int64  `json:"TransId"`  //事务Id
	Trans    string `json:"Trans"`    //事务名称
}

type Logger struct {
	Error string
	//Id (雪花算法)
	Id int64 `gorm:"primary_key;comment:Id" json:"Id,omitempty"` //Id"
	//级别 (Debug, Info, Warn, Error, Panic, Fatal)
	// Level string
	//录创建时间 (纳秒时间戳)
	TimeCreate int64 `gorm:"comment:录创建时间" json:"TimeCreate,omitempty"` //录创建时间"
	//事务Id (雪花算法)
	TransId int64 `gorm:"comment:事件Id" json:"TransId,omitempty"` //事件Id"
	//事务
	Trans string `gorm:"comment:事件" json:"Trans,omitempty"` //事件"
	//操作
	Action string `gorm:"comment:操作" json:"Action,omitempty"` //操作"
	//方法
	Method string `gorm:"comment:方法" json:"Method,omitempty"` //方法"
	//集群Id
	ServiceCluster int
	//服务名
	ServiceName string
	//服务Id
	ServiceId string
	//原始数据
	RawData string
	//应用Id
	AppId string
	//客户端IP
	ClientIP string `gorm:"comment:客户端IP" json:"ClientIP,omitempty"` //客户端IP"
	//耗时类型（QPS/服务/事件）
	TimeUsedType string `gorm:"comment:耗时类型类型(QPS/服务/事件)" json:"TimeUsedType,omitempty"` //耗时类型类型（QPS/服务/事件）"
	//耗时 (纳秒值)
	TimeUsed int64 `gorm:"comment:耗时" json:"TimeUsed,omitempty"` //耗时"
	//开始时间 (毫秒时间戳)
	TimeStart int64 `gorm:"comment:开始时间" json:"TimeStart,omitempty"` //开始时间"
	//结束时间 (毫秒时间戳)
	TimeEnd int64 `gorm:"comment:结束时间" json:"TimeEnd,omitempty"` //结束时间"
}

func NewLogger(log *Log) *Logger {
	var _log Logger
	if log != nil {
		_log.Id = log.Id
		_log.AppId = log.AppId
		_log.ClientIP = log.ClientIP
		_log.Trans = log.Trans
		_log.TransId = log.TransId
	}
	return &_log
}

func (l *Logger) GetZaps() (zfs []zapcore.Field) {
	t := reflect.TypeOf(*l)
	v := reflect.ValueOf(*l)
	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		val := v.Field(i).Interface()
		// fmt.Printf("%s: %v = %v\n", f.Name, f.Type, val)
		var zf zapcore.Field
		switch f.Type.Name() {
		case "string":
			zf = zap.String(f.Name, fmt.Sprint(val))
		case "int",
			"int8",
			"int16",
			"int32",
			"int64",
			"uint",
			"uint8",
			"uint16",
			"uint32",
			"uint64":
			zf = zap.Int64(f.Name, v.Field(i).Int())
		// case "uintptr":
		// case "float32":
		// case "float64":
		// case "complex64":
		// case "complex128":
		// case "array":
		// case "chan":
		// case "func":
		// case "interface":
		// case "map":
		// case "ptr":
		// case "slice":
		// case "bool":
		// case "struct":
		// case "unsafe.Pointer":
		default:
			continue
		}
		zfs = append(zfs, zf)
	}
	return
}
